/**
 * 账样列 - 新建或编辑界面
 * 
 * @author PSI
 * @copyright 2015 - present
 * @license GPL v3
 */
PCL.define("PSI.SLN0002.Subject.FmtColEditForm", {
  extend: "PSI.AFX.Form.EditForm",

  config: {
    subject: null,
    company: null
  },

  /**
   * @override
   */
  initComponent() {
    const me = this;

    const entity = me.getEntity();

    me.adding = entity == null;

    const buttons = [];
    if (!entity) {
      const btn = {
        text: "保存并继续新建",
        ...PSI.Const.BTN_STYLE,
        formBind: true,
        handler() {
          me._onOK(true);
        },
        scope: me
      };

      buttons.push(btn);
    }

    let btn = {
      text: "保存",
      ...PSI.Const.BTN_STYLE,
      formBind: true,
      iconCls: "PSI-button-ok",
      handler() {
        me._onOK(false);
      },
      scope: me
    };
    buttons.push(btn);

    btn = {
      text: "取消",
      ...PSI.Const.BTN_STYLE,
      handler() {
        me.close();
      },
      scope: me
    };
    buttons.push(btn);

    const t = entity == null ? "新建账样列" : "编辑账样列";
    const logoHtml = me.genLogoHtml(entity, t);

    PCL.apply(me, {
      header: {
        title: me.formatTitle(PSI.Const.PROD_NAME),
        height: 40
      },
      width: 650,
      height: 350,
      layout: "border",
      listeners: {
        show: {
          fn: me._onWndShow,
          scope: me
        },
        close: {
          fn: me._onWndClose,
          scope: me
        }
      },
      items: [{
        region: "north",
        height: 50,
        border: 0,
        html: logoHtml
      }, {
        region: "center",
        border: 0,
        layout: "fit",
        items: {
          xtype: "tabpanel",
          id: me.buildId(me, "tabPanel"),
          border: 0,
          bodyStyle: { borderWidth: 0 },
          items: [{
            title: "数据库结构",
            id: me.buildId(me, "tabDbStruct"),
            border: 0,
            layout: "fit",
            items: {
              border: 0,
              xtype: "form",
              id: me.buildId(me, "form1"),
              bodyStyle: "margin-top:10px",
              layout: {
                type: "table",
                columns: 2,
                tableAttrs: PSI.Const.TABLE_LAYOUT,
              },
              defaultType: 'textfield',
              fieldDefaults: {
                labelWidth: 60,
                labelAlign: "right",
                labelSeparator: "",
                msgTarget: 'side'
              },
              items: me.getDbStructInputs()
            }
          }, {
            title: "凭证录入",
            id: me.buildId(me, "tabVoucherInput"),
            border: 0,
            layout: "fit",
            items: {
              border: 0,
              xtype: "form",
              id: me.buildId(me, "form2"),
              bodyStyle: "margin-top:10px",
              layout: {
                type: "table",
                columns: 2,
                tableAttrs: PSI.Const.TABLE_LAYOUT,
              },
              defaultType: 'textfield',
              fieldDefaults: {
                labelWidth: 120,
                labelAlign: "right",
                labelSeparator: "",
                msgTarget: 'side'
              },
              items: me.getVoucherInputs()
            }
          }, {
            title: "账簿",
            id: me.buildId(me, "tabAcc"),
            border: 0,
            layout: "fit",
            items: {
              border: 0,
              xtype: "form",
              id: me.buildId(me, "form3"),
              bodyStyle: "margin-top:10px",
              layout: {
                type: "table",
                columns: 2,
                tableAttrs: PSI.Const.TABLE_LAYOUT,
              },
              defaultType: 'textfield',
              fieldDefaults: {
                labelWidth: 120,
                labelAlign: "right",
                labelSeparator: "",
                msgTarget: 'side'
              },
              items: me.getAccInputs()
            }
          },],
          listeners: {
            tabchange: {
              fn: me._onTabChange,
              scope: me
            },
          }
        }
      }],
      buttons,
    });

    me.callParent(arguments);

    me.editForm = PCL.getCmp(me.buildId(me, "editForm"));

    me.hiddenId = PCL.getCmp(me.buildId(me, "hiddenId"));
    me.editCaption = PCL.getCmp(me.buildId(me, "editCaption"));
    me.editName = PCL.getCmp(me.buildId(me, "editName"));
    me.hiddenType = PCL.getCmp(me.buildId(me, "hiddenFieldType"));
    me.editType = PCL.getCmp(me.buildId(me, "editFieldType"));
    me.hiddenFmtCategory = PCL.getCmp(me.buildId(me, "hiddenFmtCategory"));
    me.editFmtCategory = PCL.getCmp(me.buildId(me, "editFmtCategory"));

    me.editVoucherInputShowOrder = PCL.getCmp(me.buildId(me, "editVoucherInputShowOrder"));

    me.hiddenVoucherInput = PCL.getCmp(me.buildId(me, "hiddenVoucherInput"));
    me.editVoucherInput = PCL.getCmp(me.buildId(me, "editVoucherInput"));
    me.hiddenVoucherInputXtype = PCL.getCmp(me.buildId(me, "hiddenVoucherInputXtype"));
    me.editVoucherInputXtype = PCL.getCmp(me.buildId(me, "editVoucherInputXtype"));
    me.editVoucherInputColspan = PCL.getCmp(me.buildId(me, "editVoucherInputColspan"));
    me.editVoucherInputWidth = PCL.getCmp(me.buildId(me, "editVoucherInputWidth"));

    me.editSubAccLevel = PCL.getCmp(me.buildId(me, "editSubAccLevel"));
    me.editColWidth = PCL.getCmp(me.buildId(me, "editColWidth"));

    me.buttonRefCol = PCL.getCmp(me.buildId(me, "buttonRefCol"));
    me.editCodeTableName = PCL.getCmp(me.buildId(me, "editCodeTableName"));

    me.hiddenFmtCPM = PCL.getCmp(me.buildId(me, "hiddenFmtCPM"));
    me.editFmtCPM = PCL.getCmp(me.buildId(me, "editFmtCPM"));

    // AFX
    me.__useTabPanel = true;
    me.__tabPanelId = me.buildId(me, "tabPanel");

    me.__editorList = [
      [
        me.editCaption, me.editName, me.editType, me.editFmtCategory,
      ],
      [
        me.editVoucherInputShowOrder, me.editVoucherInputXtype, me.editVoucherInput,
        me.editVoucherInputColspan, me.editVoucherInputWidth
      ],
      [
        me.editSubAccLevel, me.editColWidth, me.editFmtCPM,
      ]
    ];


    me.form1 = PCL.getCmp(me.buildId(me, "form1"));
    me.form2 = PCL.getCmp(me.buildId(me, "form2"));
    me.form3 = PCL.getCmp(me.buildId(me, "form3"));
    me.tabPanelMain = PCL.getCmp(me.buildId(me, "tabPanel"));
  },

  /**
   * @private
   */
  getDbStructInputs() {
    const me = this;
    const entity = me.getEntity();
    const subject = me.getSubject();

    const width1 = 600;
    const width2 = 295;

    return [{
      xtype: "hidden",
      id: me.buildId(me, "hiddenId"),
      name: "id",
      value: entity == null ? null : entity.get("id")
    }, {
      xtype: "hidden",
      name: "companyId",
      value: me.getCompany().get("id")
    }, {
      xtype: "hidden",
      name: "subjectCode",
      value: me.getSubject().get("code")
    }, {
      xtype: "displayfield",
      fieldLabel: "科目",
      value: me.toFieldNoteText(`${subject.get("code")} - ${subject.get("name")}`),
      colspan: 2,
    }, {
      id: me.buildId(me, "editCaption"),
      fieldLabel: "列标题",
      width: width2,
      allowBlank: false,
      blankText: "没有输入列标题",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      name: "fieldCaption",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      }
    }, {
      id: me.buildId(me, "editName"),
      fieldLabel: "数据库字段",
      labelWidth: 100,
      width: width2,
      allowBlank: false,
      blankText: "没有输入数据库字段名称",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      name: "fieldName",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      }
    }, {
      id: me.buildId(me, "hiddenFieldType"),
      xtype: "hidden",
      name: "fieldType",
      value: "1",
    }, {
      id: me.buildId(me, "editFieldType"),
      xtype: "psi_sysdictfield",
      tableName: "t_sysdict_sln0002_fmt_field_type",
      callbackFunc: me._fieldTypeCallback,
      callbackScope: me,
      fieldLabel: "类型",
      width: width2,
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      blankText: "没有输入类型",
      allowBlank: false,
      value: "字符串",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      },
      colspan: 2,
    }, {
      id: me.buildId(me, "hiddenFmtCategory"),
      xtype: "hidden",
      name: "fmtCategory",
      value: "0",
    }, {
      id: me.buildId(me, "editFmtCategory"),
      labelWidth: 70,
      xtype: "psi_sysdictfield",
      tableName: "t_sysdict_sln0002_fmt_category",
      callbackFunc: me._fmtCategoryCallback,
      callbackScope: me,
      fieldLabel: "账样归属",
      width: width1,
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      blankText: "没有输入账样归属",
      allowBlank: false,
      value: "既是凭证字段又是账簿字段",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      },
      colspan: 2,
    },];
  },

  /**
   * @private
   */
  getVoucherInputs() {
    const me = this;

    const width1 = 600;
    const width2 = 295;

    return [{
      id: me.buildId(me, "editVoucherInputShowOrder"),
      fieldLabel: "凭证录入排序",
      labelWidth: 95,
      width: width2,
      allowBlank: false,
      blankText: "没有输入凭证录入排序",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      xtype: "numberfield",
      hideTrigger: true,
      allowDecimal: false,
      name: "voucherInputshowOrder",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      },
      value: 1,
    }, {
      id: me.buildId(me, "hiddenVoucherInputXtype"),
      xtype: "hidden",
      name: "voucherInput",
      value: "textfield",
    }, {
      id: me.buildId(me, "editVoucherInputXtype"),
      fieldLabel: "凭证录入控件",
      labelWidth: 95,
      width: width2,
      allowBlank: false,
      blankText: "没有输入凭证录入控件",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      xtype: "psi_sysdictfield",
      tableName: "t_sysdict_sln0002_fmt_voucher_input_xtype",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      },
      value: "textfield - 文本录入框",
      callbackFunc: me._voucherInputXtypeCallback,
      callbackScope: me,
    }, {
      fieldLabel: "凭证录入方式",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      labelWidth: 95,
      width: width1,
      colspan: 2,
      xtype: "fieldcontainer",
      layout: "hbox",
      items: [{
        id: me.buildId(me, "hiddenVoucherInput"),
        xtype: "hidden",
        name: "voucherInput",
        value: "1",
      }, {
        id: me.buildId(me, "editVoucherInput"),
        margin: "0 0 0 0",
        xtype: "psi_sysdictfield",
        tableName: "t_sysdict_sln0002_fmt_voucher_input",
        value: "直接录入",
        width: 300,
        allowBlank: false,
        callbackFunc: me._voucherInputCallback,
        callbackScope: me,
        blankText: "没有输入凭证录入方式",
        listeners: {
          specialkey: {
            fn: me.__onEditSpecialKey,
            scope: me
          }
        },
      }, {
        id: me.buildId(me, "buttonRefCol"),
        margin: "0 0 0 10",
        xtype: "button",
        text: "选择引用的码表",
        disabled: true,
        handler: me._onRefCodeTable,
        scope: me,
      }]
    }, {
      id: me.buildId(me, "editCodeTableName"),
      fieldLabel: "引用表名",
      labelWidth: 90,
      disabled: true,
      colspan: 2,
      width: width1,
      name: "codeTableName"
    }, {
      id: me.buildId(me, "editVoucherInputColspan"),
      fieldLabel: "控件列占位",
      labelWidth: 95,
      width: width2,
      minValue: 1,
      maxValue: 4,
      allowBlank: false,
      blankText: "没有输入控件列占位",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      xtype: "numberfield",
      hideTrigger: true,
      allowDecimal: false,
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      },
      value: 1,
    }, {
      id: me.buildId(me, "editVoucherInputWidth"),
      fieldLabel: "控件宽度",
      labelWidth: 95,
      width: width2,
      minValue: 10,
      maxValue: 1000,
      allowBlank: false,
      blankText: "没有输入控件宽度",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      xtype: "numberfield",
      hideTrigger: true,
      allowDecimal: false,
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      },
      value: 270,
    },];
  },

  /**
   * @private
   */
  getAccInputs() {
    const me = this;

    const width1 = 600;
    const width2 = 295;

    return [{
      fieldLabel: "子账簿层级",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      labelWidth: 80,
      xtype: "fieldcontainer",
      layout: "hbox",
      width: width1,
      colspan: 2,
      items: [
        {
          id: me.buildId(me, "editSubAccLevel"),
          width: 30,
          maxValue: 3,
          allowBlank: false,
          blankText: "没有输入子账簿层级",
          xtype: "numberfield",
          hideTrigger: true,
          allowDecimal: false,
          listeners: {
            specialkey: {
              fn: me.__onEditSpecialKey,
              scope: me
            }
          },
          value: -1,
        },
        {
          xtype: "displayfield",
          value: "<span style='color:#8c8c8c;font-size:12px;margin-left:20px'>备注：-1表示不是子账簿层级字段；填写1表示1级子账簿(2、3类推)，最大到3级子账簿</span>",
          width: 570,
        },
      ]
    },
    {
      id: me.buildId(me, "editColWidth"),
      fieldLabel: "列宽",
      labelWidth: 80,
      minValue: 10,
      maxValue: 1000,
      allowBlank: false,
      blankText: "没有输入列宽",
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      xtype: "numberfield",
      hideTrigger: true,
      allowDecimal: false,
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      },
      value: 100,
      colspan: 2,
    },
    {
      id: me.buildId(me, "hiddenFmtCPM"),
      xtype: "hidden",
      name: "fmtCategory",
      value: "0",
    }, {
      id: me.buildId(me, "editFmtCPM"),
      labelWidth: 90,
      xtype: "psi_sysdictfield",
      tableName: "t_sysdict_sln0002_fmt_cpm",
      callbackFunc: me._fmtCpmCallback,
      callbackScope: me,
      fieldLabel: "数量单价列",
      width: width1,
      beforeLabelTextTpl: PSI.Const.REQUIRED,
      blankText: "没有输入数量单价列",
      allowBlank: false,
      value: "非数量单价金额字段",
      listeners: {
        specialkey: {
          fn: me._onLastEditSpecialKey,
          scope: me
        }
      },
      colspan: 2,
    },
    ];
  },

  /**
   * 保存
   * 
   * @private
   */
  _onOK(thenAdd) {
    const me = this;

    // 检查数据是否录入完整
    let f = me.form1;
    if (!f.getForm().isValid()) {
      me.showInfo("数据没有录入完整", () => {
        me.tabPanelMain.setActiveTab(0);
      });

      return;
    }

    f = me.form2;
    if (!f.getForm().isValid()) {
      me.showInfo("数据没有录入完整", () => {
        me.tabPanelMain.setActiveTab(1);
      });

      return;
    }

    f = me.form3;
    if (!f.getForm().isValid()) {
      me.showInfo("数据没有录入完整", () => {
        me.tabPanelMain.setActiveTab(2);
      });

      return;
    }

    const entity = me.getEntity();
    const params = {
      id: entity == null ? null : me.getEntity().get("id"),
      companyId: me.getCompany().get("id"),
      subjectCode: me.getSubject().get("code"),
      fieldName: me.editName.getValue(),
      fieldCaption: me.editCaption.getValue(),
      fieldType: me.hiddenType.getValue(),
      fmtCategory: me.hiddenFmtCategory.getValue(),
      voucherInputShowOrder: me.editVoucherInputShowOrder.getValue(),
      voucherInputColspan: me.editVoucherInputColspan.getValue(),
      voucherInputWidth: me.editVoucherInputWidth.getValue(),
      voucherInput: me.hiddenVoucherInput.getValue(),
      voucherInputXtype: me.hiddenVoucherInputXtype.getValue(),
      codeTableName: me.editCodeTableName.getValue(),
      subAccLevel: me.editSubAccLevel.getValue(),
      colWidth: me.editColWidth.getValue(),
      fmtCPM: me.hiddenFmtCPM.getValue(),
    };

    const el = me.getEl();
    el?.mask(PSI.Const.SAVING);

    const r = {
      url: me.URL("SLN0002/Subject/editFmtCol"),
      params,
      callback(options, success, response) {
        el?.unmask();

        if (success) {
          const data = me.decodeJSON(response.responseText);
          if (data.success) {
            me._lastId = data.id;

            me.tip("数据保存成功", !thenAdd);
            me.focus();
            if (thenAdd) {
              me.clearEdit();
            } else {
              me.close();
            }
          } else {
            me.showInfo(data.msg);
          }
        } else {
          me.showInfo("网络错误");
        }
      }
    };

    me.ajax(r);
  },


  /**
   * @private
   */
  _onLastEditSpecialKey(field, e) {
    const me = this;

    if (e.getKey() == e.ENTER) {
      me._onOK(me.adding);
    }
  },

  /**
   * @private
   */
  clearEdit() {
    const me = this;
    me.editCaption.focus();

    const editors = [me.editCaption, me.editName];
    for (let i = 0; i < editors.length; i++) {
      const edit = editors[i];
      edit.setValue(null);
      edit.clearInvalid();
    }

    me.tabPanelMain.setActiveTab(0);
  },

  /**
   * @private
   */
  _onWndClose() {
    const me = this;

    PCL.WindowManager.hideAll();

    // AFX
    PCL.get(window).un('beforeunload', me.__onWindowBeforeUnload);

    if (me._lastId) {
      const parentForm = me.getParentForm();
      parentForm?.refreshFmtColsGrid.apply(parentForm, [me._lastId]);
    }
  },

  /**
   * @private
   */
  _onWndShow() {
    const me = this;

    // AFX
    PCL.get(window).on('beforeunload', me.__onWindowBeforeUnload);

    if (me.adding) {
      me.editCaption.focus();
      return;
    }

    // 下面是编辑的场景

    const el = me.getEl();
    el?.mask(PSI.Const.LOADING);
    const r = {
      url: me.URL("SLN0002/Subject/fmtColInfo"),
      params: {
        id: me.hiddenId.getValue()
      },
      callback(options, success, response) {
        el?.unmask();

        if (success) {
          const data = me.decodeJSON(response.responseText);
          me.editCaption.setValue(data.caption);
          me.editName.setValue(data.fieldName);
          me.hiddenType.setValue(data.fieldType);
          me.editType.setValue(data.fieldTypeName);

          me.hiddenFmtCategory.setValue(data.fmtCategory);
          me.editFmtCategory.setValue(data.fmtCategoryName);

          me.editVoucherInputShowOrder.setValue(data.voucherInputShowOrder);

          me.hiddenVoucherInput.setValue(data.voucherInput);
          me.editVoucherInput.setValue(data.voucherInputName);
          me.hiddenVoucherInputXtype.setValue(data.voucherInputXtype);
          me.editVoucherInputXtype.setValue(data.voucherInputXtypeName);

          me.editVoucherInputColspan.setValue(data.voucherInputColspan);
          me.editVoucherInputWidth.setValue(data.voucherInputWidth);

          me.editCodeTableName.setValue(data.codeTableName);

          const type = me.hiddenVoucherInput.getValue();
          if (type == 2) {
            // 码表录入
            me.buttonRefCol.setDisabled(false);
            me.editCodeTableName.setDisabled(false);
          }

          me.editSubAccLevel.setValue(data.subAccLevel);
          me.editColWidth.setValue(data.colWidth);

          me.hiddenFmtCPM.setValue(data.fmtCPM);
          me.editFmtCPM.setValue(data.fmtCPMName);

          // 已经创建了数据库表，字段名和类型也不能修改了
          me.editName.setReadOnly(true);
          me.editType.setReadOnly(true);

          me.editCaption.focus();
        } else {
          me.showInfo("网络错误")
        }
      }
    };

    me.ajax(r);
  },

  /**
   * 类型自定义字段回调本方法
   * @private
   */
  _fieldTypeCallback(data, scope) {
    const me = scope;

    let id = data ? data.get("id") : null;
    if (!id) {
      id = "1";
    }
    me.hiddenType.setValue(id);
  },

  /**
   * 账样归属回调本方法
   * @private
   */
  _fmtCategoryCallback(data, scope) {
    const me = scope;

    let id = data ? data.get("id") : null;
    if (!id) {
      id = "0";
    }
    me.hiddenFmtCategory.setValue(id);
  },

  /**
   * 凭证录入自定义字段回调本方法
   * @private
   */
  _voucherInputCallback(data, scope) {
    const me = scope;

    let id = data ? data.get("id") : null;
    if (!id) {
      id = "1";
    }
    me.hiddenVoucherInput.setValue(id);

    me.buttonRefCol.setDisabled(true);
    me.editCodeTableName.setDisabled(true);

    if (id == 2) {
      // 码表录入
      me.buttonRefCol.setDisabled(false);
      me.editCodeTableName.setDisabled(false);
    }
  },

  /**
   * 凭证录入控件自定义字段回调本方法
   * @private
   */
  _voucherInputXtypeCallback(data, scope) {
    const me = scope;

    let id = data ? data.get("id") : null;
    if (!id) {
      id = "1";
    }
    me.hiddenVoucherInputXtype.setValue(id);
  },

  /**
   * 数量单价列回调本方法
   * @private
   */
  _fmtCpmCallback(data, scope) {
    const me = scope;

    let id = data ? data.get("id") : null;
    if (!id) {
      id = "0";
    }
    me.hiddenFmtCPM.setValue(id);
  },

  /**
   * @private
   */
  _onRefCodeTable() {
    const me = this;

    const form = PCL.create("PSI.SLN0002.Subject.SelectColRefForm", {
      parentForm: me,
    });
    form.show();
  },

  /**
   * TabPanel选中的Tab发生改变的时候的事件处理函数
   * @private
   */
  _onTabChange(tabPanel, newCard, oldCard, eOpts) {
    const me = this;

    const id = newCard.getId();

    // 延迟0.1秒后设置input焦点
    // 这是一个奇怪的写法，不这样处理，就不能正确设置焦点
    // 原因目前不明
    PCL.Function.defer(() => {
      if (id == me.buildId(me, "tabDbStruct")) {
        me.setFocusAndCursorPosToLast(me.editCaption);
      } else if (id == me.buildId(me, "tabVoucherInput")) {
        me.setFocusAndCursorPosToLast(me.editVoucherInputShowOrder);
      } else if (id == me.buildId(me, "tabAcc")) {
        me.setFocusAndCursorPosToLast(me.editSubAccLevel);
      }
    }, 100);
  },

  /**
   * PSI.SLN0002.Subject.SelectColRefForm回调本方法
   * 
   * @private
   */
  _refColCallbackFn(data) {
    const me = this;

    me.editCodeTableName.setValue(data.tableName);
  },
});
